package cn.iocoder.yudao.module.contract.service.client;

import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.contract.dal.dataobject.company.CompanyDO;
import cn.iocoder.yudao.module.contract.dal.mysql.company.CompanyMapper;
import cn.iocoder.yudao.module.contract.dal.redis.RedisKeyConstants;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.annotations.VisibleForTesting;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import cn.iocoder.yudao.module.contract.controller.admin.client.vo.*;
import cn.iocoder.yudao.module.contract.dal.dataobject.client.ClientDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.contract.dal.mysql.client.ClientMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.contract.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_EMAIL_EXISTS;
import static java.sql.Types.INTEGER;
import static java.sql.Types.NULL;

/**
 * 客户 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class ClientServiceImpl extends ServiceImpl<ClientMapper, ClientDO> implements ClientService {

    @Resource
    private ClientMapper clientMapper;

    @Override
    public Long createClient(ClientSaveReqVO createReqVO) {
        //校验唯一
        validateUnique(createReqVO.getId(),createReqVO.getClientCode());
        // 插入
        ClientDO client = BeanUtils.toBean(createReqVO, ClientDO.class);
        clientMapper.insert(client);
        // 返回
        return client.getId();
    }

    @Override
    @CacheEvict(value = RedisKeyConstants.CLIENT_BY_NAME, key = "#updateReqVO.id")
    public void updateClient(ClientSaveReqVO updateReqVO) {
        // 校验存在
        validateClientExists(updateReqVO.getId());
        //校验唯一
        validateUnique(updateReqVO.getId(),updateReqVO.getClientCode());
        // 更新
        ClientDO updateObj = BeanUtils.toBean(updateReqVO, ClientDO.class);
        clientMapper.updateById(updateObj);
    }

    @Override
    @CacheEvict(value = RedisKeyConstants.CLIENT_BY_NAME, key = "#updateReqVO.id")
    public void deleteClient(Long id) {
        // 校验存在
        validateClientExists(id);
        // 删除
        clientMapper.deleteById(id);
    }

    private void validateClientExists(Long id) {
        if (clientMapper.selectById(id) == null) {
            throw exception(CLIENT_NOT_EXISTS);
        }

        if (clientMapper.selectById(id) == null) {
            throw exception(CLIENT_NOT_EXISTS);
        }
    }
    @VisibleForTesting
    void validateUnique(Long id, String clientCode) {
        if (StrUtil.isBlank(clientCode)) {
            return;
        }
        ClientDO data = clientMapper.selectOne(new LambdaQueryWrapper<ClientDO>().eq(ClientDO::getClientCode,clientCode));
        if (data == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的用户
        if (id == null) {
            throw exception(CLIENT_EXISTS);
        }
        if (!data.getId().equals(id)) {
            throw exception(CLIENT_EXISTS);
        }
    }

    @Override
    public ClientDO getClient(Long id) {
        return clientMapper.selectById(id);
    }

    @Override
    @Cacheable(value = RedisKeyConstants.CLIENT_BY_NAME+ "#86400", key = "#name", unless = "#result == null")
    public ClientDO getClientByName(String name) {
        //根据名称获取客户信息 缓存1天
        return getOne(new LambdaQueryWrapper<ClientDO>().eq(ClientDO::getClientName,name),false);
    }

    @Override
    public PageResult<ClientDO> getClientPage(ClientPageReqVO pageReqVO) {
        return clientMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ClientDO> getClientList(ClientDO clientDO) {
        return clientMapper.selectList( new LambdaQueryWrapperX<ClientDO>()
                .likeIfPresent(ClientDO::getClientCode, clientDO.getClientCode())
                .likeIfPresent(ClientDO::getClientName, clientDO.getClientName())
                .orderByDesc(ClientDO::getId));
    }

    @Override
    public List<ClientContractUploadCycleVO> listOpenCycleClientContractUploadCycle() {
        return clientMapper.listOpenCycleClientContractUploadCycle();
    }

    @Override
    public boolean openContractUploadCycle(long id, boolean openStatus) {
        ClientDO clientDO = new ClientDO();
        clientDO.setId(id);
        if(openStatus){
            clientDO.setContractUploadCycle(5);
        }else {
            clientDO.setContractUploadCycle(NULL);
        }

        clientDO.setOpenUploadCycle(openStatus);
        return this.updateById(clientDO);
    }
}